package net.borderwars.io;

import java.util.Date;
import java.util.Vector;

/**
 * Source code from "Java Distributed Computing", by Jim Farley.
 * <p/>
 * Classes: DataSample, DataMonitor
 * Example: 8-1
 * Description: A class useful for monitoring data flow into or out of a
 * networked application.
 */

class DataSample {
    long byteCount;
    Date start;
    Date end;

    DataSample (long bc, Date ts, Date tf) {
        byteCount = bc;
        start = ts;
        end = tf;
    }
}

public class DataMonitor {
    protected Vector<DataSample> samples;

    public DataMonitor () {
        samples = new Vector<DataSample> ();
    }

    // Add a sample with a start and finish time.
    public void addSample (long bcount, Date ts, Date tf) {
        samples.addElement (new DataSample (bcount, ts, tf));
    }

    // Get the data rate of a given sample.
    public float getRateFor (int sidx) {
        float rate = 0;
        int scnt = samples.size ();
        if (scnt > sidx && sidx >= 0) {
            DataSample s = samples.elementAt (sidx);
            Date start = s.start;
            Date end = s.end;
            if (start == null && sidx >= 1) {
                DataSample prev = samples.elementAt (sidx - 1);
                start = prev.end;
            }

            if (start != null && end != null) {
                long msec = end.getTime () - start.getTime ();
                rate = 1000 * (float) s.byteCount / (float) msec;
            }
        }

        return rate;
    }

    // Get the rate of the last sample
    public float getLastRate () {
        int scnt = samples.size ();
        return getRateFor (scnt - 1);
    }

    // Get the average rate over all samples.
    public float getAverageRate () {
        long msCount = 0;
        long byteCount = 0;
        Date start;
        Date finish;
        int scnt = samples.size ();
        for (int i = 0; i < scnt; i++) {
            DataSample ds = samples.elementAt (i);

            if (ds.start != null)
                start = ds.start;
            else
                if (i > 0) {
                    DataSample prev = samples.elementAt (i - 1);
                    start = ds.end;
                }
                else
                    start = null;

            if (ds.end != null)
                finish = ds.end;
            else
                if (i < scnt - 1) {
                    DataSample next = samples.elementAt (i + 1);
                    finish = ds.start;
                }
                else
                    finish = new Date ();

            // Only include this sample if we could figure out a start
            // and finish time for it.
            if (start != null && finish != null) {
                byteCount += ds.byteCount;
                msCount += finish.getTime () - start.getTime ();
            }
        }

        float rate = -1;
        if (msCount > 0) {
            rate = 1000 * (float) byteCount / (float) msCount;
        }

        return rate;
    }
}